﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows;
using MaxAlarm.Common;
using MaxAlarm.Common.WebQueries;
using MaxAlarm.Core.Settings;
using MaxAlarm.Core.Utility;
using MaxAlarm.Core.WebQueries;

namespace MaxAlarm.Core.Authorization
{
    public sealed class LoginManager : DependencyObject
    {
        #region Events 

        public event WebQueryResultEventHandler Success;

        private void OnSuccess()
        {
            WebQueryResultEventHandler handler = Success;
            if (handler != null) handler(this, Result);
        }

        public event ExceptionEventHandler Error;

        private void OnError(Exception exception)
        {
            ExceptionEventHandler handler = Error;
            if (handler != null) handler(this, exception);
        }

        #endregion

        #region Properties 

        public string Login { get; set; }
        public string Password { get; set; }
        public string BaseUri { get; set; }
        public WebQueryResult Result { get; private set; }

        public static readonly DependencyProperty IsBusyProperty =
            DependencyProperty.Register("IsBusy", typeof (bool), typeof (LoginManager), new PropertyMetadata(default(bool)));

        public bool IsBusy
        {
            get { return this.SafeGetValue<bool>(IsBusyProperty); }
            set { this.SafeSetValue(IsBusyProperty, value); }
        }

        public static readonly DependencyProperty BusyMessageProperty =
            DependencyProperty.Register("BusyMessage", typeof (string), typeof (LoginManager), new PropertyMetadata(default(string)));

        public string BusyMessage
        {
            get { return this.SafeGetValue<string>(BusyMessageProperty); }
            set { this.SafeSetValue(BusyMessageProperty, value); }
        }

        private BackgroundWorker _worker;

        private static readonly NameValueCollection QueryVariables = new NameValueCollection
                                                                         {
                                                                             {"server", "maximo01%3A1099%2FMXServer"},
                                                                             {"country", "RU"},
                                                                             {"language", "ru"},
                                                                             {"timezone", "Europe%2FHelsinki"},
                                                                             {"rawoffset", "7200000"},
                                                                             {"usedaylight", "true"},
                                                                             {"login.x", "-1"},
                                                                             {"login.y", "-1"}
                                                                         };

        #endregion

        #region Singletone
        private static readonly object Locker = new object();
        private static LoginManager _instance;

        public static LoginManager Instance
        {
            get
            {
                lock (Locker)
                {
                    return _instance ?? (_instance = new LoginManager());
                }
            }
        }

        private LoginManager()
        {
            
        }

        #endregion

        public void LoginAsync()
        {
            LoginAsync(Login, Password);
        }

        public void LoginAsync(string login, string pass)
        {
            Login = login;
            Password = pass;

            if (IsBusy)
            {
                OnError(new Exception("Previous operation not completed."));
                return;
            }

            BusyMessage = "Wait for login...";
            IsBusy = true;
            _worker = new BackgroundWorker {WorkerSupportsCancellation = true};
            _worker.DoWork += DoWork;
            _worker.RunWorkerCompleted += RunCompleted;
            _worker.RunWorkerAsync();
        }

        private void RunCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IsBusy = false;

            if (e.Error != null)
            {
                OnError(e.Error);
                return;
            }
            BusyMessage = "Completed...";
            OnSuccess();
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            BusyMessage = "Get url...";
            var uri = UriHelper.CombineUri(SettingsManager.Instance.Settings.BaseAddress, Properties.UriConstants.LoginPath);

            BusyMessage = "Get cookies...";
            var cookies = WebQuery.GetCookies(uri);

            QueryVariables["login"] = Login;
            QueryVariables["password"] = Password;

            BusyMessage = "Send query...";
            var query = WebQuery.Create(WebQueryType.GET, uri, cookies, QueryVariables);
            Result = query.Execute();
        }
    }
    
}
